home *** CD-ROM | disk | FTP | other *** search
- /* File: main.c
- * Created: 01-01-95
- * Updated: 30-12-95
- * Version: 1.00
- * Project: Clicker
- * Owner: Jeroen Vermeulen
- * Requirements: KickStart V39+
- * Legal: PD
- * Status: Release
- */
-
- char verstr[]="$VER: Clicker 1.0 (30.12.95) Jeroen Vermeulen",
- descrp[]="Clicker 1.0 - Public Domain";
-
- /* TODO:
- * Prefs save option!
- * Add note names to frequency display
- * Improve sound quality (longer sample perhaps?)
- */
-
- #include <proto/exec.h>
- #include <exec/libraries.h>
- #include <exec/devices.h>
- #include <exec/memory.h>
- #include <proto/dos.h>
- #include <proto/icon.h>
- #include <proto/utility.h>
- #include <proto/commodities.h>
- #include <proto/gadtools.h>
- #include <proto/alib.h>
- #include <intuition/gadgetclass.h>
-
- #include "main.h"
- #include "broker.h"
- #include "prefs.h"
- #include "sound.h"
- #include "gui.h"
-
-
- STRPTR AllocFailMsgPort = "Unable to set up message port!\n";
-
- static STRPTR
- Break_Exit = "**BREAK** -- Clicker removed\n";
-
- /* EventLoop():
- * This is where our commodity does its work. This function receives
- * CX messages and acts on them, mostly by making noises.
- * If anything should go wrong, errptr is directed to an error string
- * and the return value is set accordingly. If all is well, this should
- * be RETURN_OK.
- */
- static int EventLoop(STRPTR *const errptr,
- CxObj *const brokerobj,
- struct MsgPort *const cxport,
- struct IOAudio *const soundrequest,
- struct WindowContext *const PrefsWin)
- {
- const ULONG waitmask = SIGBREAKF_CTRL_C | (1<<(cxport->mp_SigBit));
- /* --- */
-
- for (;;)
- {
- struct Message *msg;
- BOOL closewin = FALSE;
- const ULONG gotsig = Wait(waitmask|(PrefsWin->SigMask));
-
- /* --- */
-
- if (gotsig & SIGBREAKF_CTRL_C)
- {
- *errptr = Break_Exit;
- return(RETURN_WARN);
- }
-
- while ((msg = GetMsg(cxport)))
- {
- CxMsg *const cxmsg = (CxMsg *)msg;
- ULONG msgid = CxMsgID(cxmsg);
- ULONG msgtype = CxMsgType(cxmsg);
- BOOL clicknow = FALSE;
-
- switch (msgtype)
- {
- case CXM_COMMAND: switch (msgid)
- {
- case CXCMD_DISABLE:
- ActivateCxObj(brokerobj,FALSE);
- break;
-
- case CXCMD_ENABLE:
- ActivateCxObj(brokerobj,TRUE);
- break;
-
- case CXCMD_KILL:
- return(RETURN_OK);
-
- case CXCMD_APPEAR:
- case CXCMD_UNIQUE:
- ShowWindow(errptr,PrefsWin);
- break;
-
- case CXCMD_DISAPPEAR:
- closewin = TRUE;
- break;
- }
- break;
-
- case CXM_IEVENT:
- {
- struct InputEvent *const ievent =
- (struct InputEvent *)CxMsgData(cxmsg);
-
- if (!(ievent->ie_Code & IECODE_UP_PREFIX))
- {
- switch (ievent->ie_Class)
- {
- #ifndef NOCLICKMOUSE
- case IECLASS_RAWMOUSE:
- clicknow = ClickPrefs.ClickMouse;
- break;
- #endif /* NOCLICKMOUSE */
-
- case IECLASS_RAWKEY:
- clicknow = TRUE;
- break;
-
- default:
- break;
- }
- }
- }
- break;
-
- default:
- break;
- }
- ReplyMsg(msg);
- if (clicknow) KeyClick(soundrequest);
- }
- if (PrefsWin->Shown)
- {
- struct IntuiMessage *imsg;
- /* --- */
- while ((imsg = GT_GetIMsg(PrefsWin->Win->UserPort)))
- {
- const ULONG imsg_Class = imsg->Class;
- const UWORD imsg_Code = imsg->Code;
- struct Gadget *const g = imsg->IAddress;
-
- /* --- */
-
- GT_ReplyIMsg(imsg);
-
- switch (imsg_Class)
- {
- case IDCMP_GADGETDOWN:
- case IDCMP_GADGETUP:
- case IDCMP_MOUSEMOVE:
- switch (g->GadgetID)
- {
- case mygadget_volume:
- ClickPrefs.volume = imsg_Code;
- ClickPrefs.newsettings = TRUE;
- break;
-
- case mygadget_cycles:
- ClickPrefs.cycles = imsg_Code;
- ClickPrefs.newsettings = TRUE;
- break;
-
- case mygadget_period:
- ClickPrefs.period = SliderToPeriod(imsg_Code);
- ClickPrefs.newsettings = TRUE;
- break;
-
- #ifndef NOCLICKMOUSE
- case mygadget_clickmouse:
- ClickPrefs.ClickMouse = (g->Flags & GFLG_SELECTED);
- break;
- #endif /* NOCLICKMOUSE */
-
- default:
- break;
- }
- break;
-
- case IDCMP_CLOSEWINDOW:
- closewin = TRUE;
- break;
-
- case IDCMP_REFRESHWINDOW:
- GT_BeginRefresh(PrefsWin->Win);
- GT_EndRefresh(PrefsWin->Win,TRUE);
- break;
-
- default:
- break;
- }
- }
- if (closewin) HideWindow(PrefsWin);
- }
- }
- }
-
-
- /* MatchStr():
- * Boolean frontend for stricmp(). Returns TRUE if the strings pointed to by
- * its arguments are identical (case-insensitive comparison), or FALSE if not.
- */
- static BOOL MatchStr(const STRPTR a, const STRPTR b)
- {
- return (BOOL)(Stricmp((UBYTE *)a,(UBYTE *)b)==0);
- }
-
- /* BoolAttr():
- * Returns whether a tooltype string should be interpreted as TRUE. Defaults to
- * FALSE if no string is given, but TRUE if the string is empty.
- * Hopefully this behaviour allows tooltypes to be set without arguments.
- */
- static BOOL BoolAttr(const UBYTE *const value)
- {
- UBYTE *val = (UBYTE *)value;
- if (val && (!*val || MatchStr(val,"TRUE") || MatchStr(val,"YES") ||
- MatchStr(val,"ON")))
- return TRUE;
- else return FALSE;
- }
-
-
- int main(LONG argc, UBYTE **argv)
- {
- int returnval = RETURN_FAIL;
- STRPTR error = NULL;
- BYTE CX_Priority = 0;
- BOOL cx_popup = FALSE;
-
- struct NewBroker *mybroker;
- struct IOAudio *soundrequest;
-
- /* There may already be another copy of Clicker running, so prefs settings are
- * gathered into a temporary struct to prevent them from overwriting those of
- * the active Clicker.
- */
- struct SoundSettings TempPrefs;
- /* --- */
-
- soundrequest = CreateSample(&error);
- if (soundrequest)
- {
- if ((IconBase = OpenLibrary("icon.library",36)))
- {
- UBYTE **ToolTypes;
- /* --- */
- if ((ToolTypes=ArgArrayInit(argc,argv)))
- {
- /* Read tooltype settings for click sound
- */
- TempPrefs.period = HertzToPeriod(ArgInt(ToolTypes,"PITCH",739));
- TempPrefs.volume = ArgInt(ToolTypes,"VOLUME",(ULONG)ClickPrefs.volume);
- TempPrefs.cycles = ArgInt(ToolTypes,"LENGTH",(ULONG)ClickPrefs.cycles);
-
- #ifdef NOCLICKMOUSE
- TempPrefs.ClickMouse = FALSE;
- #else /* NOCLICKMOUSE */
- TempPrefs.ClickMouse = BoolAttr(ArgString(ToolTypes,"CLICKMOUSE","NO"));
- #endif /* NOCLICKMOUSE */
-
- cx_popup = BoolAttr(ArgString(ToolTypes,"CX_POPUP","NO"));
- ArgArrayDone();
- }
- CloseLibrary(IconBase);
- }
-
- /* Unpleasantness happens if LENGTH is set to zero. Checking for this is
- * worth the bother if you ask me.
- */
- if (!TempPrefs.cycles) TempPrefs.cycles = 1;
-
- TempPrefs.newsettings = TRUE;
-
- mybroker = MakeBroker(&error, CX_Priority);
- if (mybroker)
- {
- CxObj *brokerobj;
- /* --- */
- if ((brokerobj = SetupBroker(&error,mybroker)))
- {
- struct WindowContext *PrefsWin;
- /* --- */
- if ((PrefsWin = MakeWindow(&error,cx_popup)))
- {
- CopySoundPrefs(&TempPrefs,&ClickPrefs);
- ActivateCxObj(brokerobj,TRUE);
- returnval = EventLoop(&error, brokerobj, mybroker->nb_Port,
- soundrequest, PrefsWin);
- ActivateCxObj(brokerobj,FALSE);
- DestroyWindow(PrefsWin);
- }
- DeleteCxObjAll(brokerobj);
- }
- KillBroker(mybroker);
- }
- DeleteSample(soundrequest);
- }
-
- if (error)
- {
- PutStr(error);
- }
- return(returnval);
- }
-